package me.flyray.bsin.server.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.github.binarywang.wxpay.bean.transfer.TransferBatchesRequest;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.TransferService;
import lombok.extern.slf4j.Slf4j;
import me.flyray.bsin.context.BsinServiceContext;
import me.flyray.bsin.domain.entity.*;
import me.flyray.bsin.domain.enums.AccountCategory;
import me.flyray.bsin.domain.enums.CcyType;
import me.flyray.bsin.facade.service.AccountService;
import me.flyray.bsin.facade.service.MerchantService;
import me.flyray.bsin.infrastructure.biz.paychannel.PayChannelConfigBiz;
import me.flyray.bsin.infrastructure.biz.paychannel.wxpay.payway.WxLite;

import me.flyray.bsin.payment.channel.wxpay.model.RefundUnifyReq;
import me.flyray.bsin.payment.channel.wxpay.model.UnifyOrderReq;
import me.flyray.bsin.payment.channel.wxpay.response.UnifiedOrderRes;
import me.flyray.bsin.payment.common.AbstractRes;
import me.flyray.bsin.payment.enums.PayChannelInterfaceEnum;
import me.flyray.bsin.domain.enums.TransactionStatus;
import me.flyray.bsin.domain.request.TransactionDTO;
import me.flyray.bsin.domain.request.TransactionRequest;
import me.flyray.bsin.enums.TransactionType;
import me.flyray.bsin.exception.BusinessException;
import me.flyray.bsin.facade.engine.RevenueShareServiceEngine;
import me.flyray.bsin.facade.service.TransactionService;
import me.flyray.bsin.infrastructure.mapper.*;
import me.flyray.bsin.mybatis.utils.Pagination;
import me.flyray.bsin.payment.channel.wxpay.BsinWxPayServiceUtil;
import me.flyray.bsin.server.listen.ChainTransactionListen;
import me.flyray.bsin.infrastructure.biz.TransactionBiz;
import me.flyray.bsin.security.contex.LoginInfoContextHelper;
import me.flyray.bsin.security.domain.LoginUser;
import me.flyray.bsin.utils.BsinSnowflake;
import me.flyray.bsin.utils.StringUtils;

import me.flyray.bsin.domain.entity.PayChannelConfig;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.shenyu.client.apache.dubbo.annotation.ShenyuDubboService;
import org.apache.shenyu.client.apidocs.annotations.ApiDoc;
import org.apache.shenyu.client.apidocs.annotations.ApiModule;
import org.apache.shenyu.client.dubbo.common.annotation.ShenyuDubboClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import me.flyray.bsin.payment.enums.PayWayEnum;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

import static me.flyray.bsin.constants.ResponseCode.*;
import static me.flyray.bsin.utils.Utils.ObjectToMapConverter;

/**
 * @author Admin
 * @description 针对表【waas_transaction(交易记录;)】的数据库操作Service实现
 * @createDate 2024-04-24 20:36:00
 */
@Slf4j
@ApiModule(value = "transaction")
@ShenyuDubboService(value = "/transaction", timeout = 15000)
@Transactional(rollbackFor = Exception.class)
public class TransactionServiceImpl implements TransactionService {

  // 常量定义
  private static final String PAY_RESULT_SUCCESS = "success";
  private static final int PRICE_MULTIPLY_FACTOR = 100;
  @DubboReference(version = "${dubbo.provider.version}")
  private AccountService accountService;


  @Autowired private BsinWxPayServiceUtil bsinWxPayServiceUtil;
  @Autowired private TransactionJournalMapper transactionJournalMapper;
  @Autowired private TransactionMapper transactionMapper;
  @Autowired private TransactionAuditMapper transactionAuditMapper;
  @Autowired private ChainCoinMapper chainCoinMapper;
  @Autowired private WalletAccountMapper walletAccountMapper;
  @Autowired private ChainTransactionListen chainTransactionListen;
  @Autowired private TransactionBiz transactionBiz;
  @Autowired private RevenueShareServiceEngine revenueShareServiceEngine;
  @Autowired private PayChannelConfigBiz payChannelConfigBiz;

  @Autowired private WxLite wxLite;

  /**
   * 创建交易订单 oms下单后发起调用，创建交易订单
   * 提取请求参数: 微信同意下单必须参数：payWay, payChannel, payAmount, outTradeNo(outOrderNo), appId,bizRoleAppId, notifyUrl, remark, profitSharingType, profitSharingAmount
   * 1. 创建交易订单
   * 2. 创建交易流水
   * 3. 支付操作
   *
   * @param requestMap 创建交易请求参数
   * @return 交易创建结果
   */
  @Override
  @ShenyuDubboClient("/create")
  @ApiDoc(desc = "create")
  public Map<String, Object> create(Map<String, Object> requestMap) throws UnsupportedEncodingException {
    log.info("开始创建交易订单，请求参数：{}", requestMap);
    // 获取登录用户信息
    LoginUser loginUser = LoginInfoContextHelper.getLoginUser();

    // 构建统一支付请求对象
    UnifyOrderReq unifyOrderReq = transactionBiz.buildUnifyOrderReq(loginUser, requestMap);
    // 创建或获取交易订单，并处理分账配置
    Transaction waasTransaction =
        transactionBiz.createWithProfitSharing(loginUser, unifyOrderReq);

    // 如果订单已支付成功，直接返回
    if (waasTransaction != null
        && TransactionStatus.SUCCESS.getCode().equals(waasTransaction.getTransactionStatus())) {
      log.info("订单已支付成功，直接返回，outOrderNo: {}", unifyOrderReq.getOutOrderNo());
      requestMap.put("payResult", PAY_RESULT_SUCCESS);
      return requestMap;
    }
    // 2. 创建支付流水记录
    // 查询是否已存在支付流水，避免重复创建
    TransactionJournal waasTransactionJournal =
        transactionJournalMapper.selectOne(
            new LambdaQueryWrapper<TransactionJournal>()
                .eq(TransactionJournal::getTransactionNo, waasTransaction.getSerialNo()));

    if (waasTransactionJournal == null) {
      // 创建新的支付流水记录
      waasTransactionJournal = new TransactionJournal();
      waasTransactionJournal.setTransactionNo(waasTransaction.getSerialNo());
      waasTransactionJournal.setPayAmount(unifyOrderReq.getPayAmount());
      waasTransactionJournal.setSerialNo(BsinSnowflake.getId());
      waasTransactionJournal.setStatus(TransactionStatus.PENDING.getCode());
      transactionJournalMapper.insert(waasTransactionJournal);
      log.info("支付流水记录创建成功，journalNo: {}", waasTransactionJournal.getSerialNo());
    }

    // 3. 支付处理
    AbstractRes res = null;
    if (PayChannelInterfaceEnum.WXPAY.getCode().equals(unifyOrderReq.getPayChannel())) {
      log.info("开始处理微信支付，outOrderNo: {}", unifyOrderReq.getOutOrderNo());
      PayWayEnum payWayEnum = PayWayEnum.getInstanceById(unifyOrderReq.getPayWay());
      if (payWayEnum == null) {
        log.error("不支持的支付方式：{}", unifyOrderReq.getPayWay());
        throw new BusinessException(NOT_SUPPORTED_PAY_WAY);
      }
      
      try {
        switch (payWayEnum) {
          case WX_LITE:
            res = wxLite.pay(unifyOrderReq);
            break;
          case WX_H5:
            log.warn("微信H5支付功能尚未实现");
            throw new BusinessException(NOT_SUPPORTED_PAY_WAY);
          case WX_APP:
            log.warn("微信APP支付功能尚未实现");
            throw new BusinessException(NOT_SUPPORTED_PAY_WAY);
          default:
            log.error("不支持的支付方式：{}", unifyOrderReq.getPayWay());
            throw new BusinessException(NOT_SUPPORTED_PAY_WAY);
        }
      } catch (Exception e) {
        log.error("微信支付失败：{}", e.getMessage());
        throw new BusinessException("100000", "微信支付失败：" + e.getMessage());
      }
    } else if (PayChannelInterfaceEnum.FIRE_DIAMOND.getCode().equals(unifyOrderReq.getPayChannel())) {
      // 火源支付 - 基于平台火钻进行支付
      log.info("开始处理火钻支付，outOrderNo: {}", unifyOrderReq.getOutOrderNo());
      // TODO: 实现火钻支付逻辑 - 包括余额验证、扣减等

      // 扣减客户账户余额
      Map<String, Object> reqMap = new HashMap<>();
      reqMap.put("bizRoleType", waasTransaction.getBizRoleType());
      reqMap.put("bizRoleTypeNo", waasTransaction.getFromAddress());
      reqMap.put("ccy", CcyType.CNY.getCode());
      reqMap.put("category", AccountCategory.BALANCE.getCode());
      reqMap.put("amount", waasTransaction.getTxAmount());
      reqMap.put("transactionType", TransactionType.PAY.getCode());
      reqMap.put("decimals", "2");
      accountService.outAccount(reqMap);
      res = new UnifiedOrderRes();

    } else if (PayChannelInterfaceEnum.BRAND_POINT.getCode().equals(unifyOrderReq.getPayChannel())) {
      // 品牌积分支付 - 使用商户品牌积分进行支付
      log.info("开始处理品牌积分支付，outOrderNo: {}", unifyOrderReq.getOutOrderNo());
      // TODO: 实现品牌积分支付逻辑 - 包括积分余额验证、扣减等
      log.warn("品牌积分支付功能尚未实现");
      throw new BusinessException(NOT_SUPPORTED_PAY_CHANNEL);
    } else {
      // 不支持的支付方式
      log.error("不支持的支付方式：{}", unifyOrderReq.getPayChannel());
      throw new BusinessException(NOT_SUPPORTED_PAY_CHANNEL);
    }
    log.info("交易订单创建完成，outOrderNo: {} res: {}", unifyOrderReq.getOutOrderNo(), res);
    // 更新交易订单的支付渠道配置编号 (只有微信支付时才有此字段)
    if (PayChannelInterfaceEnum.WXPAY.getCode().equals(unifyOrderReq.getPayChannel()) && unifyOrderReq != null) {
      waasTransaction.setPayChannelConfigNo(unifyOrderReq.getPayChannelConfigNo());
      transactionMapper.updateById(waasTransaction);
    }
    return ObjectToMapConverter(res);
  }

  /**
   * re 偏向于链上的交易
   *
   * @param transactionRequest
   */
  @Override
  @ShenyuDubboClient("/pay")
  @ApiDoc(desc = "pay")
  public void pay(TransactionRequest transactionRequest) {
    log.debug("请求TransactionService.pay,参数:{}", transactionRequest);
    LoginUser user = LoginInfoContextHelper.getLoginUser();
    try {
      // 查询币种是否支持
      LambdaQueryWrapper<ChainCoin> chainCoinQueryWrapper = new LambdaQueryWrapper<>();
      chainCoinQueryWrapper.eq(ChainCoin::getChainCoinKey, transactionRequest.getChainCoinKey());
      // 已上架
      chainCoinQueryWrapper.eq(ChainCoin::getStatus, 1);
      ChainCoin chainCoin = chainCoinMapper.selectOne(chainCoinQueryWrapper);
      if (chainCoin == null) {
        throw new BusinessException("CHAIN_COIN_NOT_EXIST");
      }
      // 查询用户账户状态是否正常
      QueryWrapper<WalletAccount> walletAccountQueryWrapper = new QueryWrapper<>();
      walletAccountQueryWrapper.eq("address", transactionRequest.getToAddress());
      walletAccountQueryWrapper.eq("chain_coin_no", chainCoin.getSerialNo());
      walletAccountQueryWrapper.eq("tenant_id", transactionRequest.getTenantId());
      WalletAccount walletAccounts = walletAccountMapper.selectOne(walletAccountQueryWrapper);
      if (walletAccounts == null) {}

      // 创建交易记录
      String serialNo = BsinSnowflake.getId(); // 雪花算法
      Transaction transaction = new Transaction();
      transaction.setSerialNo(serialNo);
      transaction.setOutOrderNo(transactionRequest.getOutOrderNo());
      transaction.setTransactionType(TransactionType.TRANSFER.getCode()); // 交易类型 2、转出
      transaction.setComment(transactionRequest.getComment());
      transaction.setFromAddress(transactionRequest.getFromAddress());
      transaction.setTxAmount(new BigDecimal(transactionRequest.getTxAmount()));
      transaction.setToAddress(transactionRequest.getToAddress());
      transaction.setBizRoleType(user.getBizRoleType());
      transaction.setBizRoleTypeNo(user.getBizRoleTypeNo());
      transaction.setTenantId(transactionRequest.getTenantId());
      transaction.setCreateTime(new Date());
      transaction.setCreateBy(user.getUserId());
      transactionMapper.insert(transaction);

      // TODO 调用风控方法

      // 风控审核通过，则执行转出动作
      if (true) {
        chainTransactionListen.transferOut();
      } else {
        // 风控拦截交易，进入人工审核
        TransactionAudit transactionAudit = new TransactionAudit();
        transactionAudit.setAuditYpe(1); // 1、交易转出审核
        transactionAudit.setAuditStatus(1); // 1、待审核状态
        transactionAudit.setAuditLevel(1); // 根据风控判断风险等级，暂默认为 1、低级风险
        transactionAudit.setTransactionNo(serialNo);
        transactionAudit.setCreateTime(new Date());
        transactionAudit.setCreateBy(user.getUserId());
        transactionAuditMapper.insert(transactionAudit);
      }
    } catch (BusinessException be) {
      throw be;
    } catch (Exception e) {
      e.printStackTrace();
      throw new BusinessException("SYSTEM_ERROR");
    }
  }

  @Override
  public Transaction recharge(Map<String, Object> requestMap) {
    return null;
  }

  /**
   * 处理各种类型转账交易
   *
   * @param requestMap
   * @return
   */
  @Override
  public Transaction transfer(Map<String, Object> requestMap) {
    WxPayConfig wxPayConfig = new WxPayConfig();
    TransferService wxTransferService = bsinWxPayServiceUtil.getWxTransferService(wxPayConfig);
    TransferBatchesRequest transferBatchesRequest = new TransferBatchesRequest();
    try {
      wxTransferService.transferBatches(transferBatchesRequest);
    } catch (WxPayException e) {
      e.printStackTrace();
      //        log.info("支付异常{}", e);
      throw new BusinessException("100000", "微信转账创建订单失败：" + e.getMessage());
    }
    return null;
  }

  @Override
  public Transaction withdraw(Map<String, Object> requestMap) {
    return null;
  }

  /**
   * 基于链账户的交易
   *
   * @param requestMap
   * @return
   */
  @ApiDoc(desc = "withdrawApply")
  @ShenyuDubboClient("/withdrawApply")
  @Override
  public Transaction withdrawApply(Map<String, Object> requestMap) {
    LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
    Transaction transaction = BsinServiceContext.getReqBodyDto(Transaction.class, requestMap);
    if (TransactionType.getInstanceById(transaction.getTransactionType()) == null) {
      throw new BusinessException("999", "交易类型不存在！");
    }
    transaction.setTenantId(loginUser.getTenantId());
    transaction.setFromAddress(loginUser.getBizRoleTypeNo());
    transaction.setAuditStatus("1");
    transactionMapper.insert(transaction);
    return transaction;
  }

  /**
   * 基于链账户的交易
   *
   * @param requestMap
   */
  @ApiDoc(desc = "withdrawAudit")
  @ShenyuDubboClient("/withdrawAudit")
  @Override
  public void withdrawAudit(Map<String, Object> requestMap) {
    Transaction transaction = BsinServiceContext.getReqBodyDto(Transaction.class, requestMap);
    transactionMapper.updateById(transaction);
  }

  /**
   * 退款
   * 1. 创建退款订单
   * 2. 创建退款订单成功，则调用支付渠道退款接口
   * @param requestMap
   * @return
   */
  @ApiDoc(desc = "refund")
  @ShenyuDubboClient("/refund")
  @Override
  public Map<String, Object> refund(Map<String, Object> requestMap) {
    log.info("开始处理退款请求: {}", requestMap);
    
    // 获取登录用户信息
    LoginUser loginUser = LoginInfoContextHelper.getLoginUser();

    // 生成退款序列号
    String refundSerialNo = BsinSnowflake.getId();
    
    // 1、根据前端传入的outOrderNo查询原始订单信息
    String outOrderNo = MapUtils.getString(requestMap, "outOrderNo");
    if (StringUtils.isBlank(outOrderNo)) {
      throw new BusinessException("100000", "原订单号不能为空");
    }
    Transaction originalTransaction = transactionMapper.selectoriginalTransaction(outOrderNo);
    
    // 2、构建统一退款请求对象
    RefundUnifyReq refundUnifyReq = transactionBiz.buildRefundUnifyReq(loginUser, requestMap, originalTransaction, refundSerialNo);
    
    // 3、验证退款前置条件
    transactionBiz.validateRefundConditions(originalTransaction, refundUnifyReq);
    
    // 4、创建或获取退款交易记录
    Transaction refundTransaction = transactionBiz.createRefundTransaction(loginUser, refundUnifyReq, originalTransaction);
    
    // 如果退款已经成功，直接返回
    if (TransactionStatus.SUCCESS.getCode().equals(refundTransaction.getTransactionStatus())) {
      log.info("退款交易记录状态为成功，outRefundNo: {}", refundSerialNo);
      return ObjectToMapConverter(refundTransaction);
    }
    
    // 根据订单信息查询支付渠道配置
    String payChannelConfigNo = originalTransaction.getPayChannelConfigNo();
    if (payChannelConfigNo == null || payChannelConfigNo.isEmpty()) {
      log.error("交易订单未关联支付渠道配置，outTradeNo: {}", refundUnifyReq.getOutTradeNo());
      throw new BusinessException(PAY_CHANNEL_CONFIG_NOT_EXIST);
    }
    log.info("支付渠道配置编号: {}", payChannelConfigNo);

    AtomicBoolean isCache = new AtomicBoolean(true);
    PayChannelConfig payChannelConfig = payChannelConfigBiz.queryPayChannelConfig(payChannelConfigNo,isCache);
    if (payChannelConfig == null) {
      log.error("未找到支付渠道配置，payChannelConfigNo: {}", payChannelConfigNo);
      throw new BusinessException(PAY_CHANNEL_CONFIG_NOT_EXIST);
    }
    if (!isCache.get()) {
      log.info("缓存中未查询到参数配置，从数据库中查询，重新写入缓存。。。");
      payChannelConfigBiz.setPayChannelConfigMapper(payChannelConfig);
    }
    
    // 根据支付渠道处理退款 - 使用新的退款模式
    if (PayChannelInterfaceEnum.WXPAY.getCode().equals(payChannelConfig.getPayChannel())) {
      log.info("开始处理微信退款，outRefundNo: {}", refundUnifyReq.getOutRefundNo());
      
      try {
        // 创建退款流水记录
        transactionBiz.createRefundJournal(refundTransaction, refundUnifyReq.getRefundAmount());
        
        // 调用对应的支付方式退款处理 - 参照支付的模式
        AbstractRes res = null;
        PayWayEnum payWayEnum = PayWayEnum.getInstanceById(refundUnifyReq.getPayWay());
        if (payWayEnum == null) {
          log.error("不支持的支付方式：{}", refundUnifyReq.getPayWay());
          throw new BusinessException(NOT_SUPPORTED_PAY_WAY);
        }
        
        switch (payWayEnum) {
          case WX_LITE:
            res = wxLite.refund(refundUnifyReq);
            break;
          case WX_H5:
            log.warn("微信H5退款功能尚未实现");
            throw new BusinessException(NOT_SUPPORTED_PAY_WAY);
          case WX_APP:
            log.warn("微信APP退款功能尚未实现");
            throw new BusinessException(NOT_SUPPORTED_PAY_WAY);
          default:
            log.error("不支持的支付方式：{}", refundUnifyReq.getPayWay());
            throw new BusinessException(NOT_SUPPORTED_PAY_WAY);
        }
        
        log.info("退款处理完成，outRefundNo: {} res: {}", refundUnifyReq.getOutRefundNo(), res);
        
        // 更新退款交易状态
        if (res != null && res.isSuccess()) {
          refundTransaction.setTransactionStatus(TransactionStatus.SUCCESS.getCode());
          log.info("微信退款成功，refundSerialNo: {}", refundSerialNo);
        } else {
          refundTransaction.setTransactionStatus(TransactionStatus.FAIL.getCode());
          log.warn("微信退款失败，refundSerialNo: {}", refundSerialNo);
        }
        
        // 使用TransactionBiz更新退款交易信息
        transactionBiz.updateRefundTransactionFromResponse(refundTransaction, res, originalTransaction);
        transactionMapper.updateById(refundTransaction);
        
        return ObjectToMapConverter(res);
        
      } catch (Exception e) {
        // 退款失败，更新交易状态
        refundTransaction.setTransactionStatus(TransactionStatus.FAIL.getCode());
        refundTransaction.setUpdateTime(new Date());
        transactionMapper.updateById(refundTransaction);
        
        log.error("微信退款失败：{}", e.getMessage(), e);
        throw new BusinessException("100000", "微信退款失败：" + e.getMessage());
      }
      
    } else if (PayChannelInterfaceEnum.FIRE_DIAMOND.getCode().equals(payChannelConfig.getPayChannel())) {
      // 火源支付退款
      log.info("开始处理火源支付退款，outRefundNo: {}", refundUnifyReq.getOutRefundNo());
      // TODO: 实现火源支付退款逻辑
      log.warn("火源支付退款功能尚未实现");
      throw new BusinessException(NOT_SUPPORTED_PAY_CHANNEL);
      
    } else if (PayChannelInterfaceEnum.BRAND_POINT.getCode().equals(payChannelConfig.getPayChannel())) {
      // 品牌积分支付退款
      log.info("开始处理品牌积分支付退款，outRefundNo: {}", refundUnifyReq.getOutRefundNo());
      // TODO: 实现品牌积分支付退款逻辑
      log.warn("品牌积分支付退款功能尚未实现");
      throw new BusinessException(NOT_SUPPORTED_PAY_CHANNEL);
      
    } else {
      // 不支持的支付方式
      log.error("不支持的支付方式：{}", payChannelConfig.getPayChannel());
      throw new BusinessException(NOT_SUPPORTED_PAY_CHANNEL);
    }
  }

  /**
   * 订单结算
   *
   * @param requestMap
   * @return
   */
  @ApiDoc(desc = "settlement")
  @ShenyuDubboClient("/settlement")
  @Override
  public Transaction settlement(Map<String, Object> requestMap) {
    return null;
  }

  /**
   * 业务订单完成之后调用钱包模块进行分账分润 定时任务触发调用 * @return
   *
   * @throws Exception
   */
  @ApiDoc(desc = "profitSharingSettlement")
  @ShenyuDubboClient("/profitSharingSettlement")
  @Override
  public Transaction profitSharingSettlement(Map<String, Object> requestMap) throws Exception {
    String outOrderNo = MapUtils.getString(requestMap, "outOrderNo");
    LambdaQueryWrapper<Transaction> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(Transaction::getOutOrderNo, outOrderNo);
    // 根据订单号查询交易
    Transaction transaction = transactionMapper.selectOne(queryWrapper);
    // 生态价值分配引擎
    revenueShareServiceEngine.excute(transaction);
    return transaction;
  }

  @Override
  public Transaction income(Map<String, Object> requestMap) {
    return null;
  }

  @Override
  public Transaction redeem(Map<String, Object> requestMap) {
    return null;
  }

  /**
   * @param transactionDTO fromAddress toAddress txAmount chainCoinNo
   */
  @Override
  @ShenyuDubboClient("/transferOut")
  @ApiDoc(desc = "transferOut")
  public void transferOut(TransactionDTO transactionDTO) throws Exception {
    log.debug("请求TransactionService.transferOut,参数:{}", transactionDTO);
    String fromAddress = transactionDTO.getFromAddress();
    String toAddress = transactionDTO.getToAddress();
    String contractAddress = transactionDTO.getContractAddress();
    BigDecimal txAmount = transactionDTO.getTxAmount();

    // 查询合约币种
    QueryWrapper<ChainCoin> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("status", 1);
    queryWrapper.eq("contract_address", contractAddress);
    //        queryWrapper.eq("tenant_id",tenant_id);
    ChainCoin chainCoin = chainCoinMapper.selectOne(queryWrapper);

    // 查询转出账户
    QueryWrapper<WalletAccount> walletAccountQueryWrapper = new QueryWrapper();
    walletAccountQueryWrapper.eq("address", fromAddress);
    WalletAccount walletAccount = walletAccountMapper.selectOne(walletAccountQueryWrapper);
    if (walletAccount == null) {
      throw new BusinessException("非平台钱包账户地址");
    }
    log.info("开始提现交易，账户余额为：{}", walletAccount.getBalance());
    transactionBiz.tokenTransfer(
            chainCoin.getChainIdentifier(),
            fromAddress,
            toAddress,
            contractAddress,
            txAmount.toBigInteger(),
            chainCoin.getCoinDecimal());
    BigDecimal balance = walletAccount.getBalance().subtract(txAmount);
    log.info("提现交易结束，账户余额为：{}", balance);
    walletAccount.setBalance(balance);
    walletAccountMapper.updateById(walletAccount);
  }

  @Override
  @ShenyuDubboClient("/getPageList")
  @ApiDoc(desc = "getPageList")
  public Page<Transaction> getPageList(TransactionDTO transactionDTO) {
    log.debug("请求TransactionService.pageList,参数:{}", transactionDTO);
    LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
    Pagination pagination = transactionDTO.getPagination();
    Page<Transaction> page = new Page<>(pagination.getPageNum(), pagination.getPageSize());
    LambdaQueryWrapper<Transaction> warapper = new LambdaQueryWrapper<>();
    warapper.orderByDesc(Transaction::getCreateTime);
    warapper.eq(Transaction::getTenantId, loginUser.getTenantId());
    warapper.eq(
        ObjectUtils.isNotEmpty(transactionDTO.getTransactionType()),
        Transaction::getTransactionType,
        transactionDTO.getTransactionType());
    warapper.eq(
        ObjectUtils.isNotEmpty(transactionDTO.getTransactionStatus()),
        Transaction::getTransactionStatus,
        transactionDTO.getTransactionStatus());
    return transactionMapper.selectPage(page, warapper);
  }

  @ShenyuDubboClient("/getDetail")
  @ApiDoc(desc = "getDetail")
  @Override
  public Transaction getDetail(Map<String, Object> requestMap) {
    String serialNo = MapUtils.getString(requestMap, "serialNo");
    Transaction transaction = transactionMapper.selectById(serialNo);
    return transaction;
  }

  /**
   * 根据支付方式判断处理
   *
   * @param requestMap
   * @return
   */
  @ApiDoc(desc = "queryOrder")
  @ShenyuDubboClient("/queryOrder")
  @Override
  @Transactional
  public Map<String, Object> queryOrder(Map<String, Object> requestMap) {
    //    WxPayConfig wxPayConfig = new WxPayConfig();
    //    wxPayConfig.setAppId(appId);
    //    wxPayConfig.setMchId(mchId);
    //    wxPayConfig.setMchKey(key);
    //    String apiV3Key = payChannelConfigParams.getString("apiV3Key");
    //    wxPayConfig.setApiV3Key(apiV3Key);
    //    wxPayConfig.setNotifyUrl(notifyUrl);
    //    wxPayConfig.setKeyPath(keyPath);
    //    wxPayConfig.setUseSandboxEnv(false);
    //    String outTradeNo = MapUtils.getString(requestMap, "outTradeNo");
    //    WxPayService wxPayService = bsinWxPayServiceUtil.getWxPayService(wxPayConfig);
    //    WxPayOrderQueryResult wxPayOrderQueryResult = wxPayService.queryOrder(null, outTradeNo);
    //    log.info(wxPayOrderQueryResult.toString());
    //    requestMap.put("orderResult", wxPayOrderQueryResult);
    return requestMap;
  }

  /**
   * 代付款接口
   * @param requestMap
   * @return
   */
  @ApiDoc(desc = "payForAnother")
  @ShenyuDubboClient("/payForAnother")
  public Map<String, Object> payForAnother(Map<String, Object> requestMap) {

    return null;
  }

}
